/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package phd.dupenois.changeidentifiers.algorithms.chihull.display;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Stroke;
import phd.dupenois.changeidentifiers.footprints.Footprint;
import uk.co.dupenois.geometry.Coordinate;
import uk.co.dupenois.geometry.Line;
import uk.co.dupenois.geometry.combinatorialmap.CombinatorialMap;
import uk.co.dupenois.grid.Grid;
import uk.co.dupenois.grid.GridListener;

/**
 *
 * @author mpd209
 */
public class ChiHullGrid extends Grid{

    private final static Stroke EDGE_STROKE = new BasicStroke(2f);
    private final static Stroke FOOTPRINT_STROKE = new BasicStroke(2f);
    private final static Color TRIANGULATION_COLOUR = Color.MAGENTA.darker();
    private final static Color CHIHULL_COLOUR = Color.BLUE.darker();
    private final static Color VALID_REMOVE_COLOUR = Color.ORANGE;
    private final static Color FOOTPRINT_COLOUR = Color.RED.darker();



    private Line[] triangulation;
    private Line[] chihull;
    private Line validremovalEdge;
    private Footprint footprint;

    public ChiHullGrid(GridListener listener, Container container){
        super(listener, container, 5);
        COLOUR_GRID = Color.LIGHT_GRAY;
        this.showCoordinateLabels = true;
    }

    public void drawTriangulation(Line[] lines){
        this.triangulation = lines.clone();
        this.chihull = null;
        this.validremovalEdge = null;
        this.repaint();
//        this.record();

    }

    public void drawChiHull(Line[] lines){
        this.chihull = lines.clone();
        this.triangulation = null;
        this.validremovalEdge = null;
        this.repaint();
//        this.record();
    }

    public void drawValidRemovalEdge(Line line){
        this.validremovalEdge = line.clone();
        this.repaint();
//        this.record();
    }

    public void drawFootprint(CombinatorialMap combinatorialMap){
        this.triangulation = null;
        Footprint dummyFootprint = new Footprint();
        Coordinate[] coords = combinatorialMap.getOrderedBoundaryVertices();
        Coordinate start = null;
        Coordinate first = null;
        Coordinate finish = null;
        for(Coordinate c: coords){
            if(start==null){
                start = c;
                first = c;
                continue;
            }
            finish = c;
            dummyFootprint.addLine(start, finish);
            start = finish;
        }
        dummyFootprint.addLine(finish, first);
        this.footprint = dummyFootprint;
        this.repaint();
//        this.record();
    }


    @Override
    public void paint(Graphics g){
        super.paint(g);
        if(inPlayback()) return;
        Graphics2D g2 = (Graphics2D) g;
        Stroke originalStroke = g2.getStroke();
        drawEdges(g2, triangulation, TRIANGULATION_COLOUR, EDGE_STROKE);
        drawEdges(g2, chihull, CHIHULL_COLOUR, EDGE_STROKE);
        drawEdge(g2, validremovalEdge, VALID_REMOVE_COLOUR, EDGE_STROKE);
        drawFootprint(g2, footprint, FOOTPRINT_COLOUR, FOOTPRINT_STROKE);
        g2.setStroke(originalStroke);
        

    }

    private void drawFootprint(Graphics2D g2, Footprint footprint, Color colour, Stroke stroke){
        if(footprint!=null){
            Coordinate[] coords = footprint.getCoordinates();
            Polygon polygon = new Polygon();
            Point point;
            for(Coordinate c : coords){
                point = getScreenPosition(c);
                polygon.addPoint(point.x, point.y);
            }
            g2.setStroke(stroke);
            g2.setColor(colour);
            g2.drawPolygon(polygon);
        }
    }

 

    private void drawEdge(Graphics2D g2, Line edge, Color colour, Stroke stroke){
        if(edge!=null){
            Line clone = edge.clone();
            g2.setStroke(stroke);
            g2.setColor(colour);
            Point screenStart = getScreenPosition(clone.getStart());
            Point screenFinish = getScreenPosition(clone.getFinish());
            g2.drawLine(screenStart.x, screenStart.y, screenFinish.x, screenFinish.y);
        }
    }
    private void drawEdges(Graphics2D g2, Line[] edges, Color colour, Stroke stroke){
        if(edges!=null && edges.length>0){
            Line[] clone = edges.clone();
            g2.setStroke(stroke);
            g2.setColor(colour);
            Point screenStart;
            Point screenFinish;
            for(Line line : clone ){
                screenStart = getScreenPosition(line.getStart());
                screenFinish = getScreenPosition(line.getFinish());
                g2.drawLine(screenStart.x, screenStart.y, screenFinish.x, screenFinish.y);
            }
        }
    }

}
